<!--
 * @Descripttion: 
 * @version: 
 * @Author: dudu
 * @Date: 2020-08-12 09:48:46
 * @LastEditors: dudu
 * @LastEditTime: 2020-08-24 09:38:53
-->
<script>
import { typeToComponentMapping } from './constant'
import _ from 'lodash'

export default {
  name: 'QueryPanel',
  data () {
    return {
      queryItems: [],//选中的查询项目
    }
  },
  props: {
    baseConfig: {
      type: Object,
      default: () => ({})
    }
  },
  methods: {
    // 创建一条查询条件
    createQuery (conf) {
      // 递归给config对象添加data和component属性
      const resurionSetDataFn = (conf, parentConf) => {
        const { type } = conf
        const component = typeToComponentMapping[type]
        return !conf.children ?
          {
            ...conf,
            parentConf,
            data: { value: '' },
            component
          } : {
            ...conf,
            parentConf,
            children: conf.children.map(_conf => {
              return resurionSetDataFn(_conf, parentConf)
            })
          }
      }
      const { type } = conf
      const component = typeToComponentMapping[type]

      const queryItem = {
        config: !conf.children ?
          {
            ...conf,
            parentConf: null,
            component: component,
            data: { value: '' }
          } :
          {
            ...conf,
            parentConf: null,
            children: conf.children.map(_conf => {
              return resurionSetDataFn(_conf, conf)
            })
          },

      }
      const hasItem = this.queryItems.find(item => item.config.key === queryItem.config.key)
      hasItem || this.queryItems.push(queryItem)
    },
    // 更新一条查询条件
    // TODO 目前需求暂时用不到此方法
    updateQuery (conf) {
      const queryItem = this.queryItems.find(item => item.config.key === conf.key)
      // console.log(queryItem, conf)

    },
    // 匹配到对应的查询条件配置
    getMatchedComp (key) {
      const queryConfigData = this.baseConfig.queryConfig.data
      const matchedConfig = queryConfigData.find(item => item.key === key)
      if (!matchedConfig) {
        console.error('no matched type')
        return
      }
      // 根据原始配置创建查询条件，为了避免污染copy一份
      this.createQuery(_.cloneDeep(matchedConfig))
    },
    // 递归渲染基础部件
    renderComponent (config) {
      const { data, component } = config
      return component ? <component
        config={config}
        value={data.value}
        onInput={value => {
          // 当autocomplete时 value是一个对象
          // 当datapicker时 value是一个数组
          switch (typeof value) {
            case 'string':
              data.value = value
              break;
            case 'object':
              data.value = Array.isArray(value) ? value : value && value.value
              break
            default:
              data.value = value
              break
          }
          this.$emit('changeCompValue', { value, config })
        }}
      /> : (config.children && config.children.length ? (<div class="comp-group">
        {
          config.children.map(conf => {
            return this.renderComponent(conf)
          })
        }
      </div>) : <span>no matched component</span>)
    },
    // 初始展示查询条件
    initQueryPanel () {
      const defaultConfigs = this.baseConfig.queryConfig.data.filter(config => this.baseConfig.defaultShowKeys.includes(config.key))
      defaultConfigs.forEach(conf => {
        this.createQuery(conf)
      })
    },
    // 表单校验
    validator () {
      let validStatus = true
      const resurionValidator = (config) => {
        if (!config.children) {
          config.rules.forEach(rule => {
            if (!rule.reg.test(config.data.value) || this.config.data.value == null) {
              validStatus = false
              this.$set(rule, 'result', false)
            } else {
              this.$set(rule, 'result', true)
            }
          })
        } else {
          config.children.forEach(conf => {
            resurionValidator(conf)
          })
        }
      }
      this.queryItems.forEach(item => {
        const config = item.config
        resurionValidator(config)
      })
      return validStatus
    }

  },
  render () {
    const queryConfigData = this.baseConfig.queryConfig.data
    const showCount = this.queryItems.length
    const totalCount = this.baseConfig.queryConfig.data.length
    return (
      <div class="query-panel">
        <div class='main-query-panel'>
          {
            this.queryItems.map(item => {
              const { config } = item
              return (
                <div class="query-item">
                  <div class="query-item__header">
                    <div>{config.label} <span class="tip">{config.tip}</span></div>
                    <div class={config.required || showCount === 1 ? 'disabled' : 'remove'} onClick={e => {
                      const index = this.queryItems.findIndex(item => item.config.key === config.key)
                      if (index > -1) {
                        this.queryItems.splice(index, 1)
                      }
                    }}>移除</div>
                  </div>
                  {this.renderComponent(config)}
                </div>
              )
            })
          }
        </div>

        <el-dropdown
          class={showCount < totalCount ? '' : 'disabled'}
          trigger="click"
          onCommand={key => this.getMatchedComp(key)}
        >
          <span class="el-dropdown-link">
            <i class="el-icon-plus"></i>增加
          </span>
          <el-dropdown-menu slot="dropdown">
            {
              queryConfigData.map(item => {
                let { label, key } = item
                return (
                  <el-dropdown-item command={key} disabled={!!this.queryItems.find(item => item.config.key === key)}>
                    {label}
                  </el-dropdown-item>
                )
              })
            }
          </el-dropdown-menu>
        </el-dropdown>

      </div>
    )
  },
  mounted () {
    this.initQueryPanel()

  }
}
</script>
<style   lang="scss" scoped>
.query-panel {
  width: 351px;
}
.disabled {
  span {
    pointer-events: none;
    cursor: auto;
    color: #ccc;
  }
}
/deep/ .query-item {
  margin-bottom: 10px;
  /deep/ .query-item__header {
    margin-bottom: 10px;
    justify-content: space-between;
    display: flex;
    .remove {
      display: none;
      color: #409eff;
      cursor: pointer;
    }
    .disabled {
      display: none;
    }
    .tip {
      color: #ff8282;
    }
  }
  .comp-group {
    display: flex;
    & > div:not(:first-child) {
      margin-left: 10px;
      flex: 1;
    }
    & > div:first-child {
      width: 100px;
    }
  }
}
.query-item:hover {
  .remove {
    display: inline-block;
  }
}
.el-dropdown-link {
  cursor: pointer;
  color: #409eff;
}
</style>